/*
 * DeviceData.h
 *  contain all data about each kind of driver
 *  Created on: Jan 7, 2012
 *      Author: Shimi
 */
#pragma once


#include "ExtentStatsAlgo.h"
#include <list>
#include <map>
using namespace std;

struct TotalStat{
	double kr ; //total of K read in that time
	double kw; //total of K read in that time
	double missSum ; // total read miss in that time
	double missSeq ;
	double extentsNum ;
};

class DeviceData
{
private:
	// according to artical table
	string kind; // "SSD" "FC" "SATA"
	int capacity; //# volumes for each device
	double size; // memory size 
	int cost; // dollars 
	double overhead; //per I/O in seconds 
	double readRate; // MB/second
	double writeRate; // MB/second
	int energy;
	double C; // factor for sequential miss - will be set in the future
	int deviceCount; // the number of devices in the system
	double maxUtil; // the max Utilization the user set 
	map<int,double> utilizationRecords; // all calculations of Utilization for all times
	map<int,double> utilizationRecordsU1; // all calculations of Utilization for all times
	map<int,double> utilizationRecordsU2; // all calculations of Utilization for all times
	map<int,double> utilizationRecordsU3; // all calculations of Utilization for all times
	TotalStat TotalReadWrite;
	TotalStat TotalReadWriteU1;
	TotalStat TotalReadWriteU2;
	TotalStat TotalReadWriteU3;
	
	void subReadWrite(int time ,ExtentStatsAlgo* e);
	void addReadWrite(int time ,ExtentStatsAlgo* e);
	double calcUtilization(TotalStat total);
	void saveUtil(int time, double util, double utilU1, double utilU2, double utilU3);

public:
	DeviceData(string kind, int capacity, int cost, 
				double overHead, int readReate, int writeRate, int energy);
	virtual ~DeviceData(void);
	string getKind();
	int getCapacity();
	int getCost();
	void setMaxUtil(double max);
	double getMaxUtil();
	double getOverhead();
	double getReadRate();
	double getWriteRate();
	int getDeviceCount();
	void setDeviceCount(int num);
	bool checkUtilization(int time ,ExtentStatsAlgo* entry);
	bool checkUtilization(int time ,list<ExtentStatsAlgo*> entries);
	void decUtilization(int time , ExtentStatsAlgo* entry);
	void encUtilization(int time , ExtentStatsAlgo* entry);
	void encUtilizationNoSave(int time , ExtentStatsAlgo* entry);
	void clearUtilData();
	double calcUtilGradientDescent(int i);
	double getUtilizationRecord(int time);
	double getUtilizationRecordU1(int time);
	double getUtilizationRecordU2(int time);
	double getUtilizationRecordU3(int time);
	string toString();
	double setSize(double size);
	void startOver();
};

